# -*- coding:utf-8 -*-
__author__ = 'Administrator'
import kivy
kivy.require('1.9.0')
import os
os.environ['KIVY_NO_CONFIG']= 'true'
os.environ['KIVY_NO_FILELOG']= 'true'

from kivy.config import Config
from kivy.utils import platform

Config.set('graphics', 'maxfps', 60)
if platform == 'win' or platform == 'macosx':
    Config.set('graphics', 'height', 720)
    Config.set('graphics', 'width', 384)
Config.set('widgets', 'scroll_timeout', 1000)
Config.set('widgets', 'scroll_distance', 8)
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.metrics import dp, sp
from kivy.properties import StringProperty, ObjectProperty
from composite_widget.base import RelativeComposite, Division
from composite_widget.content import LabelContent
from recycleview.recycleview import _kivy_1_9_1
from recycleview.staggered_layout import StaggeredViewMixin
from util_widget.floatlayer_scrollview import FloatLayerScrollView
from math import sin, pi

def _layout_vertical_content(prev_y, ref_h, ref_x, ref_width, content_size):
    content_y = prev_y -  0.5*(ref_h + content_size[1])
    content_x = ref_x + 0.5*(ref_width - content_size[0])
    prev_y = prev_y - ref_h
    return (prev_y, content_x, content_y)


def _vertical_contents_layout(x, y, size, padding, contents_children):
    #division 的内容垂直排版
    div_size = size
    ref_y = y + div_size[1] - padding[2]
    center_children = contents_children
    c_num = len(center_children)
    if c_num > 0:
        ref_x = x + padding[0]
        ref_w = div_size[0] - padding[0] - padding[1]
        #当div的内容为垂直排版,所有内容都按靠拢居中方式排版
        #center_content_height = sum([c.layout_size(div_size)[1] for c in center_children])
        #interval = float(div_size[1] - center_content_height) / 2.0
        interval = float(div_size[1]) / c_num
        #ref_y -= interval
        for child in center_children:
            content_size = child.layout_size(div_size)
            ref_y, pos_x, pos_y = _layout_vertical_content(ref_y, interval, ref_x, ref_w, content_size)
            child.layout_pos(pos_x, pos_y)

class VerticalContentDiv(Division):

    def _layout_contents(self, dt):
        if self._finish_layout_flg:
            #div的内容垂直布局并且等间隔居中
            _vertical_contents_layout(self.x, self.y, self.size, self._padding, self.contents_children)
            self._refresh_context_pos_size()
            self._show_contents()

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            touch.grab(self)
            composite = self.get_composite_root()
            index = composite._compute(touch.y)
            if index > -1:
                composite.show_select(index,touch.y)
            return True
        return super(VerticalContentDiv,self).on_touch_down(touch)

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            touch.ungrab(self)
            composite = self.get_composite_root()
            composite._compute(touch.y, True)
            composite.show_select(0,0, False)
        super(VerticalContentDiv,self).on_touch_up(touch)

    def on_touch_move(self, touch):
        if touch.grab_current is self:
            composite = self.get_composite_root()
            index = composite._compute(touch.y)
            if index > -1:
                composite.show_select(index, touch.y)
        super(VerticalContentDiv,self).on_touch_move(touch)
s_mark = ['A','B','C','D','E','F','G','H','I','J','K','L',
                      'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','#']
class QuickFindSlider(RelativeComposite):
    selected_text = StringProperty('')
    def __init__(self, **kwargs):
        global s_mark
        self.text = s_mark
        super(QuickFindSlider,self).__init__(**kwargs)
        self.orientation = 'vertical'
        self.size_hint_x = None
        self.width = dp(42)
        self.vertical_div = VerticalContentDiv()
        self.add_widget(self.vertical_div)
        self._add_label()
        self.peek_num = 4.3
        self.peek_height = dp(80)
        self.select_label =None
        self.contents_typesetting = 'float'

    def _add_label(self):
        vertical_div = self.vertical_div
        for i in range(27):
            label = LabelContent()
            label.color = 0.2, 0.2, 0.2, 1.0
            label.font_size = sp(16)
            label.text = self.text[i]
            label.transform = {'translate':{'x':0}}
            vertical_div.add_widget(label)

    def _compute(self, y, stop=False):
        radius = 0.5*float(self.height) / self.peek_num
        #print 'radius={} y={}'.format(radius, y)
        div = self.vertical_div
        a = self.peek_height
        min_distance = 100
        min_index = -1
        for index, label in enumerate(div.contents_children):
            if stop:
                label.translate = (0, 0)
            else:
                center_y = label.pos[1] + 0.5*label.size[1]
                if y - radius < center_y < y + radius:
                    ids = abs(center_y - y)
                    if ids < min_distance:
                        min_distance = ids
                        min_index = index
                    p = float(center_y - y + radius) / (2*radius)
                    translate_x = a*sin(p*pi)
                    label.translate = (-translate_x, 0)
                else:
                    label.translate = (0, 0)
        return min_index

    def show_select(self, index, y, show=True):
        label = self.select_label
        if not show:
            if label is not None:
                self.remove_widget(label)
                self.select_label = None
            return
        div = self.vertical_div
        if label is None:
            label = self.select_label = LabelContent()
            label.font_size = sp(26)
            label.color = 0.8,0.15,0.2,1
            self.add_widget(label)
            label.transform = {'translate':{'x': -dp(100), 'y': y - div.y - dp(13)}}
            self.selected_text = '{}'.format(self.text[index])
            label.text = self.selected_text
        else:
            w,h = label.size
            label.translate = (-dp(100), y - div.y - 0.5*h)
            self.selected_text = '{}'.format(self.text[index])
            label.text = self.selected_text

cities = ["A","阿坝","阿拉善","阿里","安康","安庆","鞍山","安顺","安阳","澳门",
          "B","北京","白银","保定","宝鸡","保山","包头","巴中","北海","蚌埠","本溪","毕节","滨州","百色","亳州",
          "C","重庆","成都","长沙","长春","沧州","常德","昌都","长治","常州","巢湖","潮州","承德","郴州","赤峰","池州","崇左","楚雄","滁州","朝阳",
          "D","大连","东莞","大理","丹东","大庆","大同","大兴安岭","德宏","德阳","德州","定西","迪庆","东营",
          "E","鄂尔多斯","恩施","鄂州",
          "F","福州","防城港","佛山","抚顺","抚州","阜新","阜阳",
          "G","广州","桂林","贵阳","甘南","赣州","甘孜","广安","广元","贵港","果洛",
          "H","杭州","哈尔滨","合肥","海口","呼和浩特","海北","海东","海南","海西","邯郸","汉中","鹤壁","河池","鹤岗","黑河","衡水","衡阳","河源","贺州","红河","淮安","淮北","怀化","淮南","黄冈","黄南","黄山","黄石","惠州","葫芦岛","呼伦贝尔","湖州","菏泽",
          "J","济南","佳木斯","吉安","江门","焦作","嘉兴","嘉峪关","揭阳","吉林","金昌","晋城","景德镇","荆门","荆州","金华","济宁","晋中","锦州","九江","酒泉",
          "K","昆明","开封","L","兰州","拉萨","来宾","莱芜","廊坊","乐山","凉山","连云港","聊城","辽阳","辽源","丽江","临沧","临汾","临夏","临沂","林芝","丽水","六安","六盘水","柳州","陇南","龙岩","娄底","漯河","洛阳","泸州","吕梁",
          "M","马鞍山","茂名","眉山","梅州","绵阳","牡丹江","N","南京","南昌","南宁","宁波","南充","南平","南通","南阳","那曲","内江","宁德","怒江",
          "P","盘锦","攀枝花","平顶山","平凉","萍乡","莆田","濮阳","Q","青岛","黔东南","黔南","黔西南","庆阳","清远","秦皇岛","钦州","齐齐哈尔","泉州","曲靖","衢州","R","日喀则","日照",
          "S","上海","深圳","苏州","沈阳","石家庄","三门峡","三明","三亚","商洛","商丘","上饶","山南","汕头","汕尾","韶关","绍兴","邵阳","十堰","朔州","四平","绥化","遂宁","随州","宿迁","宿州",
          "T","天津","太原","泰安","泰州","台州","唐山","天水","铁岭","铜川","通化","通辽","铜陵","铜仁","台湾",
          "W","武汉","乌鲁木齐","无锡","威海","潍坊","文山","温州","乌海","芜湖","乌兰察布","武威","梧州",
          "X","厦门","西安","西宁","襄樊","湘潭","湘西","咸宁","咸阳","孝感","邢台","新乡","信阳","新余","忻州","西双版纳","宣城","许昌","徐州","香港","锡林郭勒","兴安",
          "Y","银川","雅安","延安","延边","盐城","阳江","阳泉","扬州","烟台","宜宾","宜昌","宜春","营口","益阳","永州","岳阳","榆林","运城","云浮","玉树","玉溪","玉林",
          "Z","杂多县","赞皇县","枣强县","枣阳市","枣庄","泽库县","增城市","曾都区","泽普县","泽州县","札达县","扎赉特旗","扎兰屯市","扎鲁特旗","扎囊县","张北县","张店区","章贡区","张家港","张家界","张家口","漳平市","漳浦县","章丘市","樟树市","张湾区",
          "彰武县","漳县","张掖","漳州","长子县","湛河区","湛江","站前区","沾益县","诏安县","召陵区","昭平县","肇庆","昭通","赵县","昭阳区","招远市","肇源县","肇州县","柞水县","柘城县","浙江","镇安县","振安区","镇巴县","正安县","正定县","正定新区","正蓝旗","正宁县","蒸湘区","正镶白旗","正阳县","郑州","镇海区","镇江",
          "浈江区","镇康县","镇赉县","镇平县","振兴区","镇雄县","镇原县","志丹县","治多县","芝罘区","枝江市","芷江侗族自治县","织金县","中方县","中江县","钟楼区","中牟县","中宁县","中山","中山区","钟山区","钟山县","中卫","钟祥市","中阳县","中原区","周村区","周口","周宁县","舟曲县","舟山",
          "周至县","庄河市","诸城市","珠海","珠晖区","诸暨市","驻马店","准格尔旗","涿鹿县","卓尼","涿州市","卓资县","珠山区","竹山县","竹溪县","株洲","株洲县","淄博","子长县","淄川区","自贡","秭归县","紫金县","自流井区","资溪县","资兴市","资阳"]


import os
from kivy.core.text import LabelBase
from kivy.properties import ListProperty
from kivy.resources import resource_add_path
from kivy.uix.button import Button
from kivy.lang import Builder
LabelBase.get_system_fonts_dir()
resource_add_path('../fonts')
os.environ['KIVY_VALID_FONT'] = 'SourceHanSansCN-Regular.otf'

Builder.load_string('''
<MarkLabel>
    contents_typesetting: 'anchor'
    LabelContent:
        text: root.mark
        color: 0.2,0.2,0.2,1.0
        font_size: sp(18)
        margin: dp(8),0,0,0
        anchor: 'left'
<CityItem>
    canvas.before:
        Color:
            rgb: 1.0,1.0,1.0,1.0
        Rectangle:
            pos: 0,0
            size: self.size
        #背景分割线
        Color:
            rgb: 0.81,0.81,0.81
        Rectangle:
            pos: 0,0
            size: self.width,1
    contents_typesetting: 'anchor'
    LabelContent:
        text: root.label
        color: 0.2,0.2,0.2,1.0
        font_size: sp(16)
        margin: dp(8),0,0,0
        anchor: 'left'

<BoxLayoutColor>
    canvas.before:
        Color:
            rgb: self.background_color
        Rectangle:
            pos: self.pos
            size: self.size
<QuickFindPage>:
    find_view: find_view
    container: container
    orientation: 'vertical'
    BoxLayout:
        id: container
        orientation: 'vertical'
        FloatLayerScrollView:
            id: find_view
    BoxLayout:
        size_hint_y: None
        height: dp(50)
        Button:
            text: 'button1'
            on_release: root.button1_click()
        Button:
            text: 'button2'
            on_release: root.button2_click()
''')

class MarkLabel(RelativeComposite, StaggeredViewMixin):
    mark = StringProperty('')
    def __init__(self, **kwargs):
        super(MarkLabel, self).__init__(**kwargs)
        self.size_hint_y = None
        self.height = dp(32)

    def refresh_view_attrs(self, rv, data):
        self.mark = data['mark']

class CityItem(RelativeComposite, StaggeredViewMixin):
    label = StringProperty('')
    def __init__(self, **kwargs):
        super(CityItem, self).__init__(**kwargs)
        self.size_hint_y = None
        self.height = dp(48)

    def refresh_view_attrs(self, rv, data):
        self.label = data['label']

class BoxLayoutColor(BoxLayout):
    background_color = ListProperty([.91,.91,.91,1])

class QuickFindPage(BoxLayoutColor):
    find_view = ObjectProperty(None)
    container = ObjectProperty(None)
    def __init__(self, **kwargs):
        self.data = None
        self.quick_find = None
        super(QuickFindPage,self).__init__(**kwargs)
        fv = self.find_view
        if fv:
            quick_find = self.quick_find = QuickFindSlider()
            fv.add_widget(quick_find)
            fbind = quick_find.fbind if _kivy_1_9_1 else quick_find.fast_bind
            fbind('selected_text', self._selected_changed)
            fbind = fv.fbind if _kivy_1_9_1 else fv.fast_bind
            fbind('on_layout', self.layout_slider)

    def layout_slider(self, *args):
        x,y,w,h = args[1:]
        if self.quick_find:
            self.quick_find.y = y
            self.quick_find.right = x + w
            self.quick_find.height = h

    def _selected_changed(self, instance, value):
        #print 'selected value={}'.format(value)
        self._quick_find(value)

    def _quick_find(self, value):
        if self.data is not None:
            try:
                global cities
                index = cities.index(value)
                rv = self.find_view.scroll_view
                manager = rv.layout_manager
                manager.refresh_view_from_start_index(index)
            except:
                pass

    def button1_click(self,*args):
        global cities
        global s_mark
        data =[]
        for text in cities:
            if text in s_mark:
                data.append({'viewclass':'MarkLabel', 'mark':text})
            else:
                data.append({'viewclass':'CityItem', 'label':text})
        rv = self.find_view.scroll_view
        rv.data = data
        self.data = data

    def button2_click(self,*args):
        pass


class MyApp(App):
    def build(self):
        root = QuickFindPage()
        return root

MyApp().run()






